// internal/parser/parser/parser.go
package parser

import (
	"fmt"

	"NumberBase/internal/parser/ast"
	"NumberBase/internal/parser/lexer"
)

// 优先级常量
const (
	LOWEST      = 1 // 最低优先级
	AND_OR      = 2 // 逻辑运算符: AND OR
	EQUALS      = 3 // 相等运算符: == !=
	LESSGREATER = 4 // 比较运算符: > < >= <=
	SUM         = 5 // 加减运算符: + -
	PRODUCT     = 6 // 乘除运算符: * /
	PREFIX      = 7 // 前缀运算符: -X 或 !X
)

// precedences 是运算符到优先级的映射表
var precedences = map[lexer.TokenType]int{
	lexer.EQUAL:         EQUALS,
	lexer.NOT_EQUAL:     EQUALS,
	lexer.LESS:          LESSGREATER,
	lexer.LESS_EQUAL:    LESSGREATER,
	lexer.GREATER:       LESSGREATER,
	lexer.GREATER_EQUAL: LESSGREATER,
	lexer.PLUS:          SUM,
	lexer.MINUS:         SUM,
	lexer.SLASH:         PRODUCT,
	lexer.ASTERISK:      PRODUCT,
	lexer.AND:           AND_OR,
	lexer.OR:            AND_OR,
}

// 前缀表达式解析函数类型
type prefixParseFn func() (ast.Expression, error)

// 中缀表达式解析函数类型
type infixParseFn func(ast.Expression) (ast.Expression, error)

// Parser 是SQL语法分析器
type Parser struct {
	lexer          *lexer.Lexer                      // 词法分析器
	currToken      lexer.Token                       // 当前Token
	peekToken      lexer.Token                       // 下一个Token
	errors         []string                          // 错误列表
	prefixParseFns map[lexer.TokenType]prefixParseFn // 前缀解析函数
	infixParseFns  map[lexer.TokenType]infixParseFn  // 中缀解析函数
}

// NewParser 创建并初始化一个新的语法分析器
func NewParser(l *lexer.Lexer) *Parser {
	p := &Parser{
		lexer:  l,
		errors: []string{},
	}

	// 初始化前缀解析函数
	p.prefixParseFns = make(map[lexer.TokenType]prefixParseFn)
	p.registerPrefix(lexer.IDENTIFIER, p.parseIdentifier)
	p.registerPrefix(lexer.STRING, p.parseStringLiteral)
	p.registerPrefix(lexer.NUMBER, p.parseNumberLiteral)
	p.registerPrefix(lexer.LPAREN, p.parseGroupedExpression)
	p.registerPrefix(lexer.ASTERISK, p.parseAsterisk)

	// 初始化中缀解析函数
	p.infixParseFns = make(map[lexer.TokenType]infixParseFn)
	// 算术运算符
	p.registerInfix(lexer.PLUS, p.parseInfixExpression)
	p.registerInfix(lexer.MINUS, p.parseInfixExpression)
	p.registerInfix(lexer.SLASH, p.parseInfixExpression)
	p.registerInfix(lexer.ASTERISK, p.parseInfixExpression)
	// 比较运算符
	p.registerInfix(lexer.EQUAL, p.parseInfixExpression)
	p.registerInfix(lexer.NOT_EQUAL, p.parseInfixExpression)
	p.registerInfix(lexer.LESS, p.parseInfixExpression)
	p.registerInfix(lexer.LESS_EQUAL, p.parseInfixExpression)
	p.registerInfix(lexer.GREATER, p.parseInfixExpression)
	p.registerInfix(lexer.GREATER_EQUAL, p.parseInfixExpression)
	// 逻辑运算符
	p.registerInfix(lexer.AND, p.parseInfixExpression)
	p.registerInfix(lexer.OR, p.parseInfixExpression)

	// 初始化Token
	p.nextToken()
	p.nextToken()

	return p
}

// 注册前缀表达式解析函数
func (p *Parser) registerPrefix(tokenType lexer.TokenType, fn prefixParseFn) {
	p.prefixParseFns[tokenType] = fn
}

// 注册中缀表达式解析函数
func (p *Parser) registerInfix(tokenType lexer.TokenType, fn infixParseFn) {
	p.infixParseFns[tokenType] = fn
}

// nextToken 前进到下一个Token
func (p *Parser) nextToken() {
	p.currToken = p.peekToken
	p.peekToken = p.lexer.NextToken()
}

// Parse 解析SQL语句
func (p *Parser) Parse() (ast.Statement, error) {
	switch p.currToken.Type {
	case lexer.SELECT:
		return p.parseSelectStatement()
	case lexer.INSERT:
		return p.parseInsertStatement()
	case lexer.UPDATE:
		return p.parseUpdateStatement()
	case lexer.DELETE:
		return p.parseDeleteStatement()
	case lexer.CREATE:
		if p.peekTokenIs(lexer.TABLE) {
			return p.parseCreateTableStatement()
		}
		return nil, fmt.Errorf("不支持的CREATE语句")
	case lexer.DROP:
		if p.peekTokenIs(lexer.TABLE) {
			return p.parseDropTableStatement()
		}
		return nil, fmt.Errorf("不支持的DROP语句")
	case lexer.ALTER:
		if p.peekTokenIs(lexer.TABLE) {
			return p.parseAlterTableStatement()
		}
		return nil, fmt.Errorf("不支持的ALTER语句")
	default:
		return nil, fmt.Errorf("不支持的SQL语句类型: %s", p.currToken.Literal)
	}
}

// Errors 返回解析过程中的错误
func (p *Parser) Errors() []string {
	return p.errors
}

// 辅助函数

// currTokenIs 检查当前Token类型
func (p *Parser) currTokenIs(t lexer.TokenType) bool {
	return p.currToken.Type == t
}

// peekTokenIs 检查下一个Token类型
func (p *Parser) peekTokenIs(t lexer.TokenType) bool {
	return p.peekToken.Type == t
}

// expectPeek 期望下一个Token是特定类型，是则前进，否则返回错误
func (p *Parser) expectPeek(t lexer.TokenType) bool {
	if p.peekTokenIs(t) {
		p.nextToken()
		return true
	}

	p.peekError(t)
	return false
}

// peekError 添加期望Token不匹配的错误
func (p *Parser) peekError(t lexer.TokenType) {
	msg := fmt.Sprintf("行%d列%d: 期望下一个Token是%s，但得到了%s",
		p.peekToken.Line, p.peekToken.Column, t, p.peekToken.Type)
	p.errors = append(p.errors, msg)
}

// peekPrecedence 获取下一个Token的优先级
func (p *Parser) peekPrecedence() int {
	if p, ok := precedences[p.peekToken.Type]; ok {
		return p
	}
	return LOWEST
}

// currPrecedence 获取当前Token的优先级
func (p *Parser) currPrecedence() int {
	if p, ok := precedences[p.currToken.Type]; ok {
		return p
	}
	return LOWEST
}
